<?php declare(strict_types=1);

/**
 * @author      guosir
 * @copyright   2023-2025 owner
 **/

namespace Srv\Apps\Apis\Order\Ctl;

use Srv\Apps\Apis\Common\Ctl\StorageCtl;
use Srv\Apps\Apis\Common\DefCtl\DefStorageCategoryCtl;
use Srv\Apps\Proto\DTO\Order\PayGoodsAddDTO;
use Srv\Apps\Proto\DTO\Order\PayGoodsEditDTO;
use Srv\Apps\Proto\DTO\Order\PayGoodsListDTO;
use Srv\Apps\Proto\Enum\GoodsCategoryEnum;
use Srv\Apps\Proto\Enum\PayFirstEnum;
use Srv\Apps\Proto\Enum\PlatformEnum;
use Srv\Apps\Proto\Enum\YesOrNoEnum;
use Srv\Apps\Proto\VO\DbJson\GoodsPriceRemarkBuyVipVO;
use Srv\Apps\Proto\VO\DbJson\GoodsPriceRemarkLotteryVO;
use Srv\Apps\Proto\VO\DbJson\GoodsPriceRemarkRechargeVO;
use Srv\Apps\Proto\VO\Order\PayGoodsListVO;
use Srv\Apps\Proto\VO\Order\PayGoodsVO;
use Srv\Libs\Common\CommArray;
use Srv\Libs\Common\CommJson;
use Srv\Libs\Common\CommString;
use Srv\Libs\Common\CommTime;
use Srv\Libs\Frame\AuthData;
use Srv\Libs\Frame\ControllerAbstract;
use Srv\Libs\Frame\Page;
use Srv\Libs\Storage\DataMysql;

final class PayCtl extends ControllerAbstract
{
    private ?DataMysql $DbAuto              = null;     // DB-Write

    /**
     * @return static
     * tag
     */
    final public static function tag():self
    {
        $thisObject                         = self::tagGet();
        if($thisObject instanceof self){
            $thisObject->DbAuto             = self::getDbAuto();
        }
        return $thisObject;
    }

    /**
     * @param int $pgspId
     * @return array
     * getPayGoodsSrc
     */
    public function getPayGoodsSrc(int $pgspId):array
    {
        if($pgspId < 1) return [];
        $isFail         = false;
        $payGoodsRecord = $this->DbAuto->getDataOne('SELECT pgsp_id, pgsp_key, pgsp_goods_key, pgsp_platform, pgsp_packname, pgsp_name, pgsp_desc, pgsp_icon, pgsp_price, pgsp_price_old, pgsp_value, pgsp_status, pgsp_sort, pgsp_pay_apple, pgsp_pay_alipay, pgsp_pay_weixin, pgsp_pay_paypal, pgsp_pay_stripe, pgsp_category, pgsp_pay_first, pgsp_remark_data, pgsp_create_time, pgsp_update_time FROM '.$this->DbAuto->getTableNameAll('pay_goods_price').' WHERE pgsp_id='.$pgspId.' AND pgsp_delete=0', $isFail);
        if($isFail || !isset($payGoodsRecord['pgsp_id'])) return [];
        return $payGoodsRecord;
    }

    /**
     * @param array $pgspIdList
     * @return array
     * getPayGoodsSrcBatch
     */
    public function getPayGoodsSrcBatch(array $pgspIdList):array
    {
        if(count($pgspIdList) < 1) return [];
        $isFail     = false;
        $list       = $this->DbAuto->getData('SELECT pgsp_id, pgsp_key, pgsp_goods_key, pgsp_platform, pgsp_packname, pgsp_name, pgsp_desc, pgsp_icon, pgsp_price, pgsp_price_old, pgsp_value, pgsp_status, pgsp_sort, pgsp_pay_apple, pgsp_pay_googlepay, pgsp_pay_alipay, pgsp_pay_weixin, pgsp_pay_paypal, pgsp_pay_stripe, pgsp_category, pgsp_pay_first, pgsp_remark_data, pgsp_create_time, pgsp_update_time FROM '.$this->DbAuto->getTableNameAll('pay_goods_price').' WHERE pgsp_id IN('.implode(',', $pgspIdList).') AND pgsp_delete=0', $isFail);
        $listData   = [];
        if(!$isFail && CommArray::isForeach($list)) foreach ($list as $item){
            $pgspIdItem             = intval($item['pgsp_id']??0);
            if($pgspIdItem < 1) continue;
            $listData[$pgspIdItem]  = $item;
        }
        return $listData;
    }

    /**
     * @param int $pgspId
     * @return PayGoodsVO|null
     * getPayGoods
     */
    public function getPayGoods(int $pgspId):?PayGoodsVO
    {
        $payGoodsRecord     = $this->getPayGoodsSrc($pgspId);
        if(!isset($payGoodsRecord['pgsp_id'])) return null;
        return $this->getPayGoodsVO($payGoodsRecord);
    }

    /**
     * @param array $pgspIdList
     * @return array
     * getPayGoodsBatch
     */
    public function getPayGoodsBatch(array $pgspIdList):array
    {
        $list               = $this->getPayGoodsSrcBatch($pgspIdList);
        if(count($list) < 1) return [];
        $PayGoodsVOList     = [];
        foreach ($list as $item){
            $pgspIdItem                     = intval($item['pgsp_id']??0);
            if($pgspIdItem < 1) continue;
            $PayGoodsVO                     = $this->getPayGoodsVO($item);
            if(!($PayGoodsVO instanceof PayGoodsVO)) continue;
            $PayGoodsVOList[$pgspIdItem]    = $PayGoodsVO;
        }
        return $PayGoodsVOList;
    }

    /**
     * @param array $payGoodsRecord
     * @return PayGoodsVO|null
     * 组装支付产品基础信息
     */
    public function getPayGoodsVO(array $payGoodsRecord): ?PayGoodsVO
    {
        $pgspId         = intval($payGoodsRecord['pgsp_id']??0);
        if($pgspId < 1) return null;
        $PayGoodsVO     = new PayGoodsVO();
        $PayGoodsVO->setPgspId($pgspId);
        $PayGoodsVO->setKey(trim($payGoodsRecord['pgsp_key']));
        $PayGoodsVO->setGoodsKey(trim($payGoodsRecord['pgsp_goods_key']));
        $PayGoodsVO->setPlatform(intval($payGoodsRecord['pgsp_platform']));
        $PayGoodsVO->setPackName(trim($payGoodsRecord['pgsp_packname']));
        $PayGoodsVO->setName(trim($payGoodsRecord['pgsp_name']));
        $PayGoodsVO->setDesc(trim($payGoodsRecord['pgsp_desc']));
        $icon           = trim($payGoodsRecord['pgsp_icon']);
        $iconUrl        = StorageCtl::tag()->getStorageUrl($icon, true);
        $PayGoodsVO->setIcon($iconUrl);
        $PayGoodsVO->setPrice(intval($payGoodsRecord['pgsp_price']));
        $PayGoodsVO->setPriceOld(intval($payGoodsRecord['pgsp_price_old']));
        $PayGoodsVO->setValue(intval($payGoodsRecord['pgsp_value']));
        $PayGoodsVO->setStatus(YesOrNoEnum::parseValue($payGoodsRecord['pgsp_status']));
        $PayGoodsVO->setSort(intval($payGoodsRecord['pgsp_sort']));
        $PayGoodsVO->setPayApple(YesOrNoEnum::parseValue($payGoodsRecord['pgsp_pay_apple']));
        $PayGoodsVO->setPayAlipay(YesOrNoEnum::parseValue($payGoodsRecord['pgsp_pay_alipay']));
        $PayGoodsVO->setPayWeixin(YesOrNoEnum::parseValue($payGoodsRecord['pgsp_pay_weixin']));
        $PayGoodsVO->setPayPaypal(YesOrNoEnum::parseValue($payGoodsRecord['pgsp_pay_paypal']));
        $PayGoodsVO->setPayStripe(YesOrNoEnum::parseValue($payGoodsRecord['pgsp_pay_stripe']));
        $category       = GoodsCategoryEnum::parseValue($payGoodsRecord['pgsp_category']);
        $PayGoodsVO->setCategory($category);
        $PayGoodsVO->setPayFirst(PayFirstEnum::parseValue($payGoodsRecord['pgsp_pay_first']));
        $remarkData     = CommJson::decodeArray(trim($payGoodsRecord['pgsp_remark_data']));
        if($category == GoodsCategoryEnum::GOODS_CATEGORY_VIP){
            $GoodsPriceRemarkBuyVipVO   = new GoodsPriceRemarkBuyVipVO();
            $GoodsPriceRemarkBuyVipVO->setDayNum(intval($remarkData['dayNum']??0));
            $GoodsPriceRemarkBuyVipVO->setLabelText($remarkData['labelText']??'');
            $PayGoodsVO->setVipRemarkData($GoodsPriceRemarkBuyVipVO);
        }
        if($category == GoodsCategoryEnum::GOODS_CATEGORY_RECHARGE){
            $GoodsPriceRemarkRechargeVO = new GoodsPriceRemarkRechargeVO();
            $GoodsPriceRemarkRechargeVO->setGiveNum(intval($remarkData['giveNum']??0));
            $GoodsPriceRemarkRechargeVO->setGiveExpire(intval($remarkData['giveExpire']??0));
            $GoodsPriceRemarkRechargeVO->setLabelText($remarkData['labelText']??'');
            $PayGoodsVO->setRechargeRemarkData($GoodsPriceRemarkRechargeVO);
        }
        if($category == GoodsCategoryEnum::GOODS_CATEGORY_LOTTERY){
            $GoodsPriceRemarkLotteryVO  = new GoodsPriceRemarkLotteryVO();
            $GoodsPriceRemarkLotteryVO->setLotteryNum(intval($remarkData['lotteryNum']??0));
            $PayGoodsVO->setLotteryRemarkData($GoodsPriceRemarkLotteryVO);
        }
        $PayGoodsVO->setCreateTime(intval($payGoodsRecord['pgsp_create_time']));
        $PayGoodsVO->setUpdateTime(intval($payGoodsRecord['pgsp_update_time']));
        return $PayGoodsVO;
    }

    /**
     * @param Page $Page
     * @param array $whereData
     * @return PayGoodsListVO|null
     * getPayGoodsList
     */
    public function getPayGoodsList(Page $Page, array $whereData): ?PayGoodsListVO
    {
        $limitString        = $Page->getLimitString();
        $whereString        = ' WHERE pgsp_delete=0 ';
        // 检索条件
        if(count($whereData) > 0)foreach ($whereData as $key => $val){
            switch ($key){
                case PayGoodsListDTO::_pgspId:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'pgsp_id='. intval($val);
                    break;
                case PayGoodsListDTO::_key:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'pgsp_key LIKE \'%'.$this->DbAuto->getRealEscapeString($val).'%\'';
                    break;
                case PayGoodsListDTO::_platform:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'pgsp_platform='. intval($val);
                    break;
                case PayGoodsListDTO::_name:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'pgsp_name LIKE \'%'.$this->DbAuto->getRealEscapeString($val).'%\'';
                    break;
                case PayGoodsListDTO::_status:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'pgsp_status='.intval($val);
                    break;
                case PayGoodsListDTO::_payApple:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'pgsp_pay_apple='.intval($val);
                    break;
                case PayGoodsListDTO::_payAlipay:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'pgsp_pay_alipay='.intval($val);
                    break;
                case PayGoodsListDTO::_payWeixin:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'pgsp_pay_weixin='.intval($val);
                    break;
                case PayGoodsListDTO::_payPaypal:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'pgsp_pay_paypal='.intval($val);
                    break;
                case PayGoodsListDTO::_payGoogle:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'pgsp_pay_googlepay='.intval($val);
                    break;
                case PayGoodsListDTO::_category:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'pgsp_category='.intval($val);
                    break;
                case PayGoodsListDTO::_payStripe:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'pgsp_pay_stripe='.intval($val);
                    break;
                case PayGoodsListDTO::_payFirst:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'pgsp_pay_first='.intval($val);
                    break;
            }
        }
        $isFail             = false;
        $sql                = 'SELECT SQL_CALC_FOUND_ROWS pgsp_id, pgsp_key, pgsp_goods_key, pgsp_platform, pgsp_packname, pgsp_name, pgsp_desc, pgsp_icon, pgsp_price, pgsp_price_old, pgsp_value, pgsp_status, pgsp_sort, pgsp_pay_apple, pgsp_pay_googlepay, pgsp_pay_alipay, pgsp_pay_weixin, pgsp_pay_paypal, pgsp_pay_stripe, pgsp_category, pgsp_pay_first, pgsp_remark_data, pgsp_create_time, pgsp_update_time FROM '.$this->DbAuto->getTableNameAll('pay_goods_price').$whereString.' ORDER BY pgsp_id DESC '.$limitString;
        $payGoodsRecordList = $this->DbAuto->getData($sql, $isFail);
        $totalNum           = $this->DbAuto->getDataInt('SELECT FOUND_ROWS() as num', 'num');
        if($isFail) return null;
        $PayGoodsVOList     = [];
        if(CommArray::isForeach($payGoodsRecordList)){
            $pgspIdList     = array_map('intval', array_column($payGoodsRecordList, 'pgsp_id'));
            $psgpIdToList   = $this->getPayGoodsRetainListBatch($pgspIdList);
            foreach($payGoodsRecordList as $payGoodsRecord){
                $pgspIdItem         = intval($payGoodsRecord['pgsp_id']);
                if($pgspIdItem < 1) continue;
                $PayGoodsVO         = $this->getPayGoodsVO($payGoodsRecord);
                if(!($PayGoodsVO instanceof PayGoodsVO)) continue;
                if(isset($psgpIdToList[$pgspIdItem]) && $psgpIdToList[$pgspIdItem] > 0)$PayGoodsVO->setPgspIdTo($psgpIdToList[$pgspIdItem]);
                $PayGoodsVOList[]   = $PayGoodsVO;
            }
        }
        $PayGoodsListVO         = new PayGoodsListVO();
        $PayGoodsListVO->setList($PayGoodsVOList);
        $PayGoodsListVO->setPage($Page->getPageVO($totalNum));
        return $PayGoodsListVO;
    }

    /**
     * @param array $setData
     * @return int
     * payGoodsAdd
     */
    public function payGoodsAdd(array $setData):int
    {
        if(count($setData) < 1) return 0;
        $setString      = '';
        $remarkJson     = '[]';
        $pgspIdTo       = 0;
        foreach ($setData as $key => $val){
            switch ($key){
                case PayGoodsAddDTO::_goodsKey:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_goods_key=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case PayGoodsAddDTO::_platform:
                    $platform       = intval($val);
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_platform='.intval($val);
                    if($platform === PlatformEnum::PLATFORM_APPLE){
                        $setString  .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_pay_apple=1, pgsp_pay_googlepay=0, pgsp_pay_alipay=0, pgsp_pay_weixin=0, pgsp_pay_paypal=0, pgsp_pay_stripe=0';
                    }else if($platform === PlatformEnum::PLATFORM_ANDROID){
                        $setString  .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_pay_apple=0, pgsp_pay_googlepay=1, pgsp_pay_alipay=1, pgsp_pay_weixin=1, pgsp_pay_paypal=0, pgsp_pay_stripe=0';
                    }else if($platform === PlatformEnum::PLATFORM_WEB){
                        $setString  .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_pay_apple=0, pgsp_pay_googlepay=0, pgsp_pay_alipay=0, pgsp_pay_weixin=0, pgsp_pay_paypal=1, pgsp_pay_stripe=1';
                    }
                    break;
                case PayGoodsAddDTO::_packName:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_packname=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case PayGoodsAddDTO::_name:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_name=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case PayGoodsAddDTO::_desc:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_desc=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case PayGoodsAddDTO::_iconKey:
                    $dsacId         = DefStorageCategoryCtl::tag()->getIdByKey(DefStorageCategoryCtl::KEY_PAY_GOODS_ICON);
                    if($dsacId < 1) return 0;
                    $saveUrl        = StorageCtl::tag()->getStorageUrlRecord(AuthData::getLoginUserId(), $dsacId, $val);
                    if(strlen($saveUrl) < 1) return 0;
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_icon=\''.$this->DbAuto->getRealEscapeString($saveUrl).'\'';
                    break;
                case PayGoodsAddDTO::_price:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_price='.intval($val);
                    break;
                case PayGoodsAddDTO::_priceOld:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_price_old='.intval($val);
                    break;
                case PayGoodsAddDTO::_value:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_value='.intval($val);
                    break;
                case PayGoodsAddDTO::_status:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_status='.intval($val);
                    break;
                case PayGoodsAddDTO::_sort:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_sort='.intval($val);
                    break;
                case PayGoodsAddDTO::_category:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_category='.intval($val);
                    break;
                case PayGoodsAddDTO::_payFirst:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_pay_first='.intval($val);
                    break;
                case PayGoodsAddDTO::_rechargeRemark:
                    if(!isset($setData[PayGoodsAddDTO::_category])) return 0;
                    if($setData[PayGoodsAddDTO::_category] === GoodsCategoryEnum::GOODS_CATEGORY_RECHARGE){
                        $remarkJson = CommJson::encodeArray($val);
                    }
                    break;
                case PayGoodsAddDTO::_vipRemark:
                    if(!isset($setData[PayGoodsAddDTO::_category])) return 0;
                    if($setData[PayGoodsAddDTO::_category] === GoodsCategoryEnum::GOODS_CATEGORY_VIP){
                        $remarkJson = CommJson::encodeArray($val);
                    }
                    break;
                case PayGoodsAddDTO::_lotteryRemark:
                    if(!isset($setData[PayGoodsAddDTO::_category])) return 0;
                    if($setData[PayGoodsAddDTO::_category] === GoodsCategoryEnum::GOODS_CATEGORY_LOTTERY){
                        $remarkJson = CommJson::encodeArray($val);
                    }
                    break;
                case PayGoodsAddDTO::_pgspIdTo:
                    $pgspIdTo       = intval($val);
                    break;
            }
        }
        if(strlen($setString) < 1) return 0;
        $currTime       = CommTime::getTimeStamp(0);
        $payGoodsKey    = $this->getPayGoodsKey();
        $isFail         = false;
        $sql            = 'INSERT INTO '.$this->DbAuto->getTableNameAll('pay_goods_price').' SET '.$setString.', pgsp_remark_data=\''.$this->DbAuto->getRealEscapeString($remarkJson).'\', pgsp_key=\''.$this->DbAuto->getRealEscapeString($payGoodsKey).'\', pgsp_delete=0, pgsp_create_time='.$currTime.', pgsp_update_time='.$currTime;
        $pgspId      = $this->DbAuto->getDataId($sql, $isFail);
        if($isFail || $pgspId < 1) return 0;
        if($pgspIdTo > 0) $this->updatePayGoodsRetain($pgspId, $pgspIdTo);
        return $pgspId;
    }

    /**
     * @param int $pgspId
     * @param array $setData
     * @return bool
     * payGoodsEdit
     */
    public function payGoodsEdit(int $pgspId, array $setData):bool
    {
        if($pgspId < 1 || count($setData) < 1) return false;
        $setString      = '';
        $updateRetain   = false;
        foreach ($setData as $key => $val){
            switch ($key){
                case PayGoodsEditDTO::_goodsKey:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_goods_key=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case PayGoodsEditDTO::_platform:
                    $platform       = intval($val);
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_platform='.$platform;
                    if($platform === PlatformEnum::PLATFORM_APPLE){
                        $setString  .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_pay_apple=1, pgsp_pay_googlepay=0, pgsp_pay_alipay=0, pgsp_pay_weixin=0, pgsp_pay_paypal=0, pgsp_pay_stripe=0';
                    }else if($platform === PlatformEnum::PLATFORM_ANDROID){
                        $setString  .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_pay_apple=0, pgsp_pay_googlepay=1, pgsp_pay_alipay=1, pgsp_pay_weixin=1, pgsp_pay_paypal=0, pgsp_pay_stripe=0';
                    }else if($platform === PlatformEnum::PLATFORM_WEB){
                        $setString  .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_pay_apple=0, pgsp_pay_googlepay=0, pgsp_pay_alipay=0, pgsp_pay_weixin=0, pgsp_pay_paypal=1, pgsp_pay_stripe=1';
                    }
                    break;
                case PayGoodsEditDTO::_packName:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_packname=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case PayGoodsEditDTO::_name:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_name=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case PayGoodsEditDTO::_desc:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_desc=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case PayGoodsEditDTO::_iconKey:
                    $dsacId         = DefStorageCategoryCtl::tag()->getIdByKey(DefStorageCategoryCtl::KEY_PAY_GOODS_ICON);
                    if($dsacId < 1) return false;
                    $saveUrl        = StorageCtl::tag()->getStorageUrlRecord(AuthData::getLoginUserId(), $dsacId, $val);
                    if(strlen($saveUrl) < 1) return false;
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_icon=\''.$this->DbAuto->getRealEscapeString($saveUrl).'\'';
                    break;
                case PayGoodsEditDTO::_price:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_price='.intval($val);
                    break;
                case PayGoodsEditDTO::_priceOld:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_price_old='.intval($val);
                    break;
                case PayGoodsEditDTO::_value:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_value='.intval($val);
                    break;
                case PayGoodsEditDTO::_status:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_status='.intval($val);
                    break;
                case PayGoodsEditDTO::_sort:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_sort='.intval($val);
                    break;
                case PayGoodsEditDTO::_category:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_category='.intval($val);
                    break;
                case PayGoodsEditDTO::_payFirst:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_pay_first='.intval($val);
                    break;
                case PayGoodsEditDTO::_rechargeRemark:
                    if(!isset($setData[PayGoodsEditDTO::_category])) return false;
                    if($setData[PayGoodsEditDTO::_category] === GoodsCategoryEnum::GOODS_CATEGORY_RECHARGE){
                        $remarkJson = CommJson::encodeArray($val);
                        $setString  .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_remark_data=\''.$this->DbAuto->getRealEscapeString($remarkJson).'\'';
                    }
                    break;
                case PayGoodsEditDTO::_vipRemark:
                    if(!isset($setData[PayGoodsEditDTO::_category])) return false;
                    if($setData[PayGoodsEditDTO::_category] === GoodsCategoryEnum::GOODS_CATEGORY_VIP){
                        $remarkJson = CommJson::encodeArray($val);
                        $setString  .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_remark_data=\''.$this->DbAuto->getRealEscapeString($remarkJson).'\'';
                    }
                    break;
                case PayGoodsEditDTO::_lotteryRemark:
                    if(!isset($setData[PayGoodsEditDTO::_category])) return false;
                    if($setData[PayGoodsEditDTO::_category] === GoodsCategoryEnum::GOODS_CATEGORY_LOTTERY){
                        $remarkJson = CommJson::encodeArray($val);
                        $setString  .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_remark_data=\''.$this->DbAuto->getRealEscapeString($remarkJson).'\'';
                    }
                    break;
                case PayGoodsEditDTO::_pgspIdTo:
                    $updateRetain   = true;
                    $pgspIdTo       = intval($val);
                    break;
            }
        }
        if(strlen($setString) < 1 && !$updateRetain) return false;
        if(strlen($setString) > 0){
            $isFail         = false;
            $currTime       = CommTime::getTimeStamp(0);
            $sql            = 'UPDATE '.$this->DbAuto->getTableNameAll('pay_goods_price').' SET '.$setString.', pgsp_update_time='.$currTime.' WHERE pgsp_id='.$pgspId.' AND pgsp_delete=0';
            if($this->DbAuto->getDataNum($sql, $isFail) < 1 || $isFail) return false;
            if($updateRetain && isset($pgspIdTo)) $this->updatePayGoodsRetain($pgspId, $pgspIdTo);
        }else{
            if(isset($pgspIdTo)) $this->updatePayGoodsRetain($pgspId, $pgspIdTo);
        }
        return true;
    }

    /**
     * @return string
     * getPayGoodsKey
     */
    public function getPayGoodsKey():string
    {
        $minLength          = 8;        // 最小长度
        $maxLength          = 16;       // 最大长度
        $maxNum             = 200;
        $currNum            = 1;
        $indexNum           = 1;
        $payGoodsKey        = strtolower(CommString::genRandStr($minLength));
        while($currNum <= $maxNum){
            $pgspIdFind     = $this->DbAuto->getDataInt('SELECT pgsp_id FROM '.$this->DbAuto->getTableNameAll('pay_goods_price').' WHERE binary pgsp_key=\''.$this->DbAuto->getRealEscapeString($payGoodsKey).'\'', 'pgsp_id');
            if($pgspIdFind < 1) break;
            if($indexNum >= 50){                // 失败自增长度1
                $indexNum   = 0;
                $minLength  += 1;
            }
            if($minLength > $maxLength) break;  // 长度封顶
            $payGoodsKey    = strtolower(CommString::genRandStr($minLength));
            ++$indexNum;
            ++$currNum;
        }
        return $payGoodsKey;
    }

    /**
     * @param array $pgspIdFromList
     * @return array
     * getPayGoodsRetainListBatch
     */
    public function getPayGoodsRetainListBatch(array $pgspIdFromList):array
    {
        $listData       = [];
        if(count($pgspIdFromList) < 1) return $listData;
        $isFail         = false;
        $sql            = 'SELECT pgsr_id, pgsp_id_from, pgsp_id_to FROM '.$this->DbAuto->getTableNameAll('pay_goods_retain').' WHERE pgsp_id_from IN('.implode(',', $pgspIdFromList).') AND pgsr_delete=0 ORDER BY pgsr_id DESC';
        $list           = $this->DbAuto->getData($sql, $isFail);
        if($isFail || !CommArray::isForeach($list)) return $listData;
        foreach($list as $item){
            $pgsrIdItem             = intval($item['pgsr_id']??0);
            if($pgsrIdItem < 1) continue;
            $psgpIdFrom             = intval($item['pgsp_id_from']??0);
            $psgpIdTo               = intval($item['pgsp_id_to']??0);
            $listData[$psgpIdFrom]  = $psgpIdTo;
        }
        return $listData;
    }

    /**
     * @param int $pgspIdFrom
     * @param int $pgspIdTo
     * @return bool
     * 更新挽留付费项关系
     */
    public function updatePayGoodsRetain(int $pgspIdFrom, int $pgspIdTo):bool
    {
        if($pgspIdFrom < 1 || $pgspIdTo < 0) return false;
        $isFail     = false;
        $info       = $this->DbAuto->getDataOne('SELECT pgsr_id, pgsp_id_from, pgsp_id_to FROM '.$this->DbAuto->getTableNameAll('pay_goods_retain').' WHERE pgsp_id_from='.$pgspIdFrom.' ORDER BY pgsr_id DESC', $isFail);
        if($isFail) return false;
        $pgsrId     = intval($info['pgsr_id']??0);
        $currTime   = CommTime::getTimeStamp(0);
        if($pgsrId < 1){
            $pgsrId = $this->DbAuto->getDataId('INSERT INTO '.$this->DbAuto->getTableNameAll('pay_goods_retain').' SET pgsp_id_from='.$pgspIdFrom.', pgsp_id_to='.$pgspIdTo.', pgsr_delete=0, pgsr_create_time='.$currTime.', pgsr_update_time='.$currTime);
            return $pgsrId > 0;
        }else{
            return $this->DbAuto->getDataNum('UPDATE '.$this->DbAuto->getTableNameAll('pay_goods_retain').' SET pgsp_id_to='.$pgspIdTo.', pgsr_update_time='.$currTime.', pgsr_delete=0 WHERE pgsr_id='.$pgsrId.' AND pgsp_id_from='.$pgspIdFrom.' AND pgsr_delete=0') > 0;
        }
    }
}